package server

import (
	"log"
	"net"
	"sync"

	"github.com/gorilla/websocket"
)

// Session websocket连接
type Session struct {
	puId   string
	wsConn *websocket.Conn
	mux    sync.Mutex

	connId      uint8
	connections map[uint8]*TcpConnection
}

func NewSession(puId string, wsConn *websocket.Conn) *Session {
	return &Session{
		puId:        puId,
		wsConn:      wsConn,
		connections: map[uint8]*TcpConnection{},
	}
}

func (tis *Session) Handle() {
	defer func() {
		for _, conn := range tis.connections {
			_ = conn.conn.Close()
		}
		_ = tis.wsConn.Close()
	}()

	for {
		_, data, err := tis.wsConn.ReadMessage()
		if err != nil {
			break
		}

		var object JsonProto
		if err = object.Unmarshal(data); err != nil {
			log.Println(err)
			continue
		}

		if conn, ok := tis.connections[object.ConnId]; ok {
			switch object.Method {
			case ProtoMethodMsg:
				conn.Write(&object)
			case ProtoMethodClose:
				conn.CloseConnection()
				delete(tis.connections, object.ConnId)
			}
		}
	}

}

func (tis *Session) NewTCP(netConn *net.TCPConn, puId string) *TcpConnection {
	tis.mux.Lock()
	defer tis.mux.Unlock()

	tis.connId++
	conn := NewTcpConnection(tis, netConn, puId, tis.connId)

	tis.connections[conn.connId] = conn

	return conn
}

func (tis *Session) DeleteTCP(connId uint8) {
	tis.mux.Lock()
	defer tis.mux.Unlock()

	delete(tis.connections, connId)
}

func (tis *Session) Write(object *JsonProto) {
	// 加锁保护
	tis.mux.Lock()
	defer tis.mux.Unlock()

	data, _ := object.Marshal()

	_ = tis.wsConn.WriteMessage(websocket.BinaryMessage, data)
}
